﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using BrnMall.Business;
using BrnMall.Core;
using BrnMall.Manager.Domain.Distribution;
using BrnMall.Manager.Manager.Distribution;
using BrnMall.Manager.Manager.Store;
using BrnMall.Manager.Manager.WeApp;
using BrnMall.Services;
using BrnMall.Services.Redlock;
using BrnMall.WeiXin.Sdk;
using PetaPoco;
using QIDong.WeApp.Models;
using QIDong.WeApp.Util;
using WeiTap.Restful;
using WeiTap.Restful.Result;

namespace QIDong.WeApp.Controllers
{
    /// <summary>
    /// 分销管理
    /// </summary>
    public class DistributorController : WebApi
    {
        /// <summary>
        /// 获取分销商信息
        /// </summary>
        /// <param name="userId">当前用户ID</param>
        /// <param name="storeId">当前店铺ID</param>
        /// <param name="disId">上级分销商用户ID</param>
        /// <param name="agentId">上级代理商用户ID</param>
        /// <returns></returns>
        public DistributorOutDto GetDistributorAndCreate(int userId, int storeId, int disId = 0, int agentId = 0)
        {
            if (disId < 0) throw new ArgumentOutOfRangeException(nameof(disId));
            if (agentId < 0) throw new ArgumentOutOfRangeException(nameof(agentId));
            if (userId <= 0) throw new ArgumentOutOfRangeException(nameof(userId));
            try
            {
                var dis = Distributors.GetDistributorAndCreate(userId, storeId, disId, agentId);
                var result = CastFromDistributor(dis);
                return result;
            }
            catch (Exception e)
            {
                Trace.TraceError(e.Message);
                Trace.TraceError(e.StackTrace);
                throw;
            }
        }

        /// <summary>
        ///获取分销设置 
        /// </summary>
        /// <param name="storeId"></param>
        /// <returns></returns>
        public string GetDistributorSet(int storeId=0)
        {
            if (storeId<=0)
                throw new Exception("店铺不存在。");
            try
            {
                var dis = Distributors.GetDistributorSet(storeId);
                return dis;
            }
            catch (Exception e)
            {
                Trace.TraceError(e.Message);
                Trace.TraceError(e.StackTrace);
                throw;
            }
        }
        /// <summary>
        /// 兼容旧的代码
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="storeId"></param>
        /// <param name="disId"></param>
        /// <param name="agentId"></param>
        /// <param name="storeappid"></param>
        /// <returns></returns>
        public DistributorOutDto GetDistributorAndCreateOpen(int userId, int storeId, int disId = 0, int agentId = 0, int storeappid = 0)
        {
            return GetDistributorAndCreate(userId, storeId, disId, agentId);
        }

        /// <summary>
        /// 获取分销商的小程序二维码
        /// </summary>
        /// <param name="id">分销商ID</param>
        /// <param name="weAppId">小程序配置ID</param>
        /// <param name="storeAppId">自动打包的小程序ID</param>
        /// <returns></returns>
        public string GetWxaCodeFile(int id, int weAppId = 0, int storeAppId = 0)
        {
            if (id < 0) throw new ArgumentOutOfRangeException(nameof(id));
            try
            {
                var dis = DistributorManager.GetDistributor(id);
                if (dis == null)
                    throw new Exception("未开通分销商功能");
                var path = dis.IsAgent == 0 ? $"/pages/index/index?agentId={dis.AgentDId}&disId={dis.Id}" : $"/pages/index/index?agentId={dis.Id}&disId=0";
                if (storeAppId == 0 && weAppId == 0)
                {
                    //采用
                    var parUserInfo = Users.GetPartUserById(dis.UserId);
                    storeAppId = parUserInfo.StoreAppId;
                }
                if (storeAppId == 0)
                {
                    var acode = WxQRCode.GetWxaCode(dis.StoreId, path, weAppId);
                    return acode;
                }
                return WxQRCode.GetWxaCodeByStoreAppId(dis.StoreId, path, storeAppId);
            }
            catch (Exception e)
            {
                Trace.TraceError(e.Message);
                throw;
            }
        }

        /// <summary>
        /// 获取请求下载小程序码的链接地址
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public string GetWxaCodeDownLoadUrl(string fileName)
        {
            var filePath = IOHelper.GetMapPath($"/upload/user/{fileName}");
            if (System.IO.File.Exists(filePath)) return $"{BMAConfig.MallConfig.SiteUrl}/upload/user/{fileName}";
            var client = new WebClient();
            client.DownloadFile($"http://static.711688.net.cn/upload/user/{fileName}", filePath);
            return $"{BMAConfig.MallConfig.SiteUrl}/upload/user/{fileName}";
        }

        /// <summary>
        /// 获取分销佣金记录
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="page">当前页</param>
        /// <param name="itemsPerPage">每页条数，默认15条</param>
        /// <returns></returns>
        public Page<BrokerageOutDto> GetBrokerages(int userId, long page = 1, long itemsPerPage = 15)
        {
            try
            {
                var result = new Page<BrokerageOutDto>();
                var brokerage = BrokerageManager.GetBrokerageUserListPage(userId, page, itemsPerPage);
                result.CurrentPage = brokerage.CurrentPage;
                result.ItemsPerPage = brokerage.ItemsPerPage;
                result.TotalItems = brokerage.TotalItems;
                result.TotalPages = brokerage.TotalPages;
                result.Items = brokerage.Items.Select(CastFromBrokerage).ToList();
                return result;
            }
            catch (Exception e)
            {
                Trace.TraceError(e.Message);
                Trace.TraceError(e.StackTrace);
                throw;
            }
        }
        /// <summary>
        /// 管理员获取分销佣金记录
        /// </summary>
        /// <returns></returns>
        public Page<BrokerageOutDto> AdminGetBrokerages(int storeId, string disStoreName, string tradeTimeStart, string tradeTimeEnd, string orderNo, long page, long itemsPerPage)
        {
            try
            {
                DateTime timeStart;
                DateTime timeEnd;
                if (!DateTime.TryParse(tradeTimeStart, out timeStart))
                {
                    timeStart = DateTime.Now.AddDays(-30).Date;
                }
                if (!DateTime.TryParse(tradeTimeEnd, out timeEnd))
                {
                    timeEnd=DateTime.Now.Date;
                }
                var result = new Page<BrokerageOutDto>();
                var brokerage = BrokerageManager.GetBrokerageStoreListPage(storeId,disStoreName, timeStart, timeEnd, orderNo, page, itemsPerPage);
                result.CurrentPage = brokerage.CurrentPage;
                result.ItemsPerPage = brokerage.ItemsPerPage;
                result.TotalItems = brokerage.TotalItems;
                result.TotalPages = brokerage.TotalPages;
                result.Items = brokerage.Items.Select(CastFromBrokerage).ToList();
                return result;
            }
            catch (Exception e)
            {
                Trace.TraceError(e.Message);
                Trace.TraceError(e.StackTrace);
                throw;
            }
        }
        /// <summary>
        /// 管理员删除佣金明细
        /// </summary>
        /// <param name="id">分拥编号</param>
        /// <returns></returns>
        public bool AdminDeleteBrokerage(int id)
        {
            return BrokerageManager.DeleteBrokerage(id);
        }

        /// <summary>
        /// 获取我的分销团队,如果为代理商获取所有下级分销商，如果是分销商获取所有一级和二级分销商
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="page"></param>
        /// <param name="itemsPerPage"></param>
        /// <returns></returns>
        public Page<DistributorOutDto> GetDistributorTeam(int userId, long page, long itemsPerPage)
        {
            try
            {
                var dis = DistributorManager.GetDistributorByUserId(userId);
                if (dis == null) throw new Exception("没有开通分销功能");
                var result = new Page<DistributorOutDto>();
                if (dis.IsAgent == 0) //分销商
                {
                    var childDis = DistributorManager.GetDistributorChildList(dis.Id, dis.StoreId, page, itemsPerPage);
                    result.Items = childDis.Items.Select(CastFromDistributor).ToList();
                    result.CurrentPage = childDis.CurrentPage;
                    result.ItemsPerPage = childDis.ItemsPerPage;
                    result.TotalItems = childDis.TotalItems;
                    result.TotalPages = childDis.TotalPages;
                }
                else//总代理
                {
                    var childDis = DistributorManager.GetAgentChildList(dis.Id, page, itemsPerPage);
                    result.Items = childDis.Items.Select(CastFromDistributor).ToList();
                    result.CurrentPage = childDis.CurrentPage;
                    result.ItemsPerPage = childDis.ItemsPerPage;
                    result.TotalItems = childDis.TotalItems;
                    result.TotalPages = childDis.TotalPages;
                }
                return result;
            }
            catch (Exception e)
            {
                Trace.TraceError(e.Message);
                throw;
            }
        }

        /// <summary>
        /// 佣金提现
        /// </summary>
        /// <param name="userId">提现人</param>
        /// <param name="storeId">店铺ID</param>
        /// <param name="money">提现金额</param>
        /// <param name="phone">联系电话</param>
        /// <returns></returns>
        public bool BrokerageRequest(int userId, int storeId, decimal money, string phone)
        {
            try
            {
                if (userId < 1 || storeId < 1 || money <= 0) throw new Exception("参数数据错误");
                var oauth = OAuths.GetOAuthUserByUid(userId);
                if (oauth == null || !oauth.Server.Equals("weapp", StringComparison.InvariantCultureIgnoreCase))
                    throw new Exception("不是微信端登录的客户暂时不能提现：未找到相关的客户或OPENID");
                var dis = DistributorManager.GetDistributorByUserId(userId);
                if (dis == null) throw new Exception("未开通分销功能");
                if (money < 1) throw new Exception("最低提现额度为1元");
                if (dis.AccountBalance < money) throw new Exception("客户额度不足");
                var user = Users.GetPartUserById(userId);
                var request = new BrokerageRequest
                {
                    PhoneNumber = phone,
                    UserId = userId,
                    Amount = money,
                    Remark = "小程序客户端提现",
                    RequestOpenId = oauth.OpenId,
                    RequestTime = DateTime.Now,
                    UserName = user.NickName,
                    StoreId = storeId,
                    Brsn = Orders.GenerateOSN(storeId, userId, 0, DateTime.Now)
                };
                dis.AccountBalance -= money;
                DistributorManager.UpdateDistributor(dis);
                return BrokerageManager.AddBrokerageRequest(request) > 0;

            }
            catch (Exception e)
            {
                Trace.TraceError(e.Message);
                throw;
            }
        }
        /// <summary>
        /// 获取提现记录
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="page">当前页</param>
        /// <param name="itemsPerPage">每页多少条，默认15</param>
        /// <returns></returns>
        public Page<BrokerageRequestOutDto> GetBrokerageRequestList(int userId, long page = 1, long itemsPerPage = 15)
        {
            try
            {
                var brl = BrokerageManager.GetBrokerageRequestUserListPage(userId, -1, -1, page, itemsPerPage);
                var result = new Page<BrokerageRequestOutDto>
                {
                    Items = brl.Items.Select(CastFromBrokerageRequest).ToList(),
                    CurrentPage = brl.CurrentPage,
                    ItemsPerPage = brl.ItemsPerPage,
                    TotalItems = brl.TotalItems,
                    TotalPages = brl.TotalPages
                };
                return result;
            }
            catch (Exception e)
            {
                Trace.TraceError(e.Message);
                throw;
            }
        }

        #region 私有
        private static DistributorOutDto CastFromDistributor(Distributor dis)
        {
            return new DistributorOutDto()
            {
                Id = dis.Id,
                UserId = dis.UserId,
                StoreId = dis.StoreId,
                AgentDId = dis.AgentDId,
                GradeId = dis.GradeId,
                DisGrade = DistributorManager.GetGrade(dis.GradeId),
                ParentId = dis.ParentId,
                Path = dis.Path,
                OrdersTotal = dis.OrdersTotal,
                OrdersCount = dis.OrdersCount,
                AccountBalance = dis.AccountBalance,
                RequestBalance = dis.RequestBalance,
                IsAgent = dis.IsAgent,
                Status = dis.Status,
                DisLevel = dis.DisLevel,
                CreateTime = dis.CreateTime,
                DisStoreName = dis.DisStoreName,
                LinkMan = dis.LinkMan,
                PhoneNumber = dis.PhoneNumber,
                ShowLogo = dis.ShowLogo
            };
        }

        private static BrokerageOutDto CastFromBrokerage(Brokerage t)
        {
            var result = new BrokerageOutDto()
            {
                Id = t.Id,
                UserId = t.UserId,
                Distributor = DistributorManager.GetDistributorByUserId(t.UserId),
                StoreId = t.StoreId,
                OrderNo = t.OrderNo,
                TradeTime = t.TradeTime,
                OrderAmount = t.OrderAmount,
                BrokerageAmount = t.BrokerageAmount,
                BrokerageType = t.BrokerageType,
                Status = t.Status,
                Remark = t.Remark,
                ApprovedUserId = t.ApprovedUserId,
                ApprovedUserName = t.ApprovedUserName,
                ApprovedTime = t.ApprovedTime,
                BrokerageRise = t.BrokerageRise,
                TradeUser = Users.GetPartUserById(t.TradeUserId)
            };
            return result;
        }

        private static BrokerageRequestOutDto CastFromBrokerageRequest(BrokerageRequest r)
        {
            var result = new BrokerageRequestOutDto
            {
                Id = r.Id,
                UserId = r.UserId,
                UserName = r.UserName,
                RequestType = r.RequestType,
                Amount = r.Amount,
                ApprovedTime = r.ApprovedTime,
                ApprovedUserId = r.ApprovedUserId,
                ApprovedUserName = r.ApprovedUserName,
                PhoneNumber = r.PhoneNumber,
                Remark = r.Remark,
                RequestBankAccount = r.RequestBankAccount,
                RequestBankName = r.RequestBankName,
                RequestOpenId = r.RequestOpenId,
                RequestTime = r.RequestTime,
                SendTime = r.SendTime,
                RequestUserRealName = r.RequestUserRealName,
                Status = r.Status,
                PayStatus = r.PayStatus,
                Brsn = r.Brsn

            };



            return result;
        }




        #endregion


    }
}

